.global _setjmp 
.global longjmp 
.extern wrap_p 

.section .data 
msg:
.ascii "\033[32mDEBUG\033[0m\n\0"

.section .text
_setjmp:
    pop     %rdx
    movq    %rbx, 0(%rdi)     /* save rbx */
    movq    %rbp, 8(%rdi)     /* save rbp/ebp */
    movq    %rsp, 16(%rdi)    /* save rsp/esp */
    movq    %r12, 24(%rdi)    /* save r12 */
    movq    %r13, 32(%rdi)    /* save r13 */
    movq    %r14, 40(%rdi)    /* save r14 */
    movq    %r15, 48(%rdi)    /* save r15 */
    movq    %rdx, 56(%rdi)    /* save pc */
    xorq    %rax, %rax
    jmp    *%rdx

/*
    void longjmp(env,val)
    env store in %rdi   
    val store in %esi
*/
/*
    x86-64 asm stack pointer rsp at a function begin must align 0x10 bytes and
    `call xxx` will push 8bytes ret address at stack pointer current position,
    for these reasons when you `call xxx` , rsp must align 0x10*n-8 
*/
longjmp:
#ifdef DEBUG
    pushq    %rbp
    movq     %rsp,%rbp
    subq     $0x10,%rsp
    movq     %rdi,-8(%rbp)
    movl     %esi,-0x10(%rbp)
    lea      msg(%rip),%rdi
    call     wrap_p
    movq     -8(%rbp),%rdi
    movl     -0x10(%rbp),%esi
    // movq     %rbp,%rsp
    // popq     %rbp 
    leave    
#endif
    movl    %esi, %eax
    /* if val is zero, we must return 1 -- otherwise return val */
    testl   %eax, %eax
    jne     .Lskip
    movl    $1, %eax
.Lskip:
            
    movq    0(%rdi), %rbx     /* restore rbx */
    movq    8(%rdi), %rbp     /* restore rbp */
    movq    16(%rdi), %rsp    /* restore rsp */
    movq    24(%rdi), %r12    /* restore r12 */
    movq    32(%rdi), %r13    /* restore r13 */
    movq    40(%rdi), %r14    /* restore r14 */
    movq    48(%rdi), %r15    /* restore r15 */
    movq    56(%rdi), %rdx    /* restore pc  */
    jmp    *%rdx



